package com.bolt.admin.module.sys.service;


import com.bolt.admin.module.sys.dto.OrgDTO;
import com.bolt.admin.module.sys.dto.OrgQueryCriteria;
import com.bolt.admin.module.sys.entity.AreaEntity;
import com.bolt.admin.module.sys.entity.OrgEntity;
import com.bolt.admin.module.sys.entity.UserEntity;
import com.bolt.admin.module.sys.repository.OrgRepository;
import com.bolt.admin.module.sys.service.converter.OrgConverter;
import com.bolt.support.base.service.BaseTreeService;
import com.bolt.support.spring.jpa.jpql.Clauses;
import com.bolt.support.spring.jpa.repository.BasicJpaRepository;
import com.bolt.support.spring.jpa.specification.QueryHelp;
import com.bolt.support.ui.tree.vo.UITreeNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;

/**
 * Auto Generate Javadoc
 *
 * @author 米超
 *         日期:2018-02-27 14:20:36
 *         机构信息
 **/
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class OrgService extends BaseTreeService<OrgEntity, String> {

    @Autowired
    private OrgRepository orgRepository;

    @Autowired
    private AreaService areaService;


    @Override
    protected BasicJpaRepository<OrgEntity, String> getRepository() {
        return orgRepository;
    }


    public List <OrgEntity> queryOrg(OrgQueryCriteria criteria) {
        Sort sort = Sort.by(Sort.Direction.ASC, "orderRank");
        List <OrgEntity> orgEntities = orgRepository
                .findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), sort);
        return orgEntities;
    }

    @Transactional(rollbackFor = Exception.class)
    public OrgEntity saveOrUpdate(OrgDTO orgDTO) {
        OrgEntity entity = OrgConverter.toEntity(orgDTO);
        AreaEntity areaEntity = areaService.findByAreaCode(orgDTO.getAreaCode());
        entity.setAreaInfo(areaEntity);
        if (entity.isNew()) {
            String code = nextCode(entity, "code");
            entity.setCode(code);
        }
        save(entity);
        return entity;
    }

    @Transactional(rollbackFor = Exception.class)
    public void del(OrgEntity org){
        this.delete(org);
        List<OrgEntity> subOrgs = findChildren(org);
        for(OrgEntity subOrg : subOrgs){
            updateSubCnt(subOrg.getId());
        }
    }

    private void updateSubCnt(String orgId){
        if(orgId != null){
            long count = findCount(k->k.lambda().eq(OrgEntity::getPid,orgId).build());
            this.jpaQueryFactory.update(OrgEntity.class)
                    .set(Clauses.of(OrgEntity::getPid), null)
                    .set(Clauses.of(OrgEntity::getChildrenSize),(int)count)
                    .where(k->k.eq(Clauses.of(OrgEntity::getId),orgId))
                    .execute();
        }
    }

    @Override
    protected void converterTreeNode(OrgEntity org, UITreeNode treeNode) {
        super.converterTreeNode(org,treeNode);
        treeNode.setName(org.getName());
        treeNode.putAttribute("areaCode", org.getAreaCode());
        treeNode.putAttribute("code", org.getCode());
        treeNode.putAttribute("enabled", Boolean.toString(org.getEnabled()));
    }

    /**
     * 验证机构关联用户情况用于删除校验
     *
     * @param ids
     * @return
     */
    public boolean verification(Set <String> ids) {
        long count = jpaQueryFactory.query().from(Clauses.of(UserEntity.class)).where(
                Clauses.of().in(Clauses.of(UserEntity::getOrgId), ids)
        ).fetchCount();
        return count > 0l;
    }
}


